package com.han.bom;

import java.util.ArrayList;

/**
 * The Exam class represents an Exam copy as specified by a professor 
 * @author Ric Janus Sapasap
 * @since JDK 1.7
 * @version 1.0
 * @see ExamResponse
 * @see Question
 * @see Professor
 */
public abstract class Exam {
	private String examID;
	private String examName;
	private ArrayList<Question> questions;
	private static int totalNumExams;
	private long duration;
	private double passingPercent;
	private boolean draft;
	
	/**
	 * gets the unique examID for the instance
	 * @return returns the unique examID
	 */
	public String getExamID() {
		return examID;
	}

	/**
	 * sets this instance's examID to the parameter
	 * @param examID the examID
	 */
	public void setExamID(String examID) {
		this.examID = examID;
	}

	/**
	 * returns a string representing the name of the exam
	 * @return the exam name
	 */
	public String getExamName() {
		return examName;
	}

	/**
	 * sets a string to represent the name of the exam
	 * @param examName the string value of the new exam name
	 */
	public void setExamName(String examName) {
		this.examName = examName;
	}

	/**
	 * an ArrayList of the questions included in the exam 
	 * @return the ArrayList of questions
	 * @see ArrayList
	 */
	public ArrayList<Question> getQuestions() {
		return questions;
	}

	/**
	 * sets this exam's questions to the specified ArrayList of Questions
	 * @param questions an ArrayList of Questions
	 * @see ArrayList
	 */
	public void setQuestions(ArrayList<Question> questions) {
		this.questions = questions;
	}
	

	/**
	 * gets the number of total existing exams
	 * @return the total number of existing exams 
	 */
	protected static int getTotalNumExams() {
		return totalNumExams;
	}

	/**
	 * sets the total number of exams to the parameter
	 * @param totalNumExams the new value
	 */
	protected static void setTotalNumExams(int totalNumExams) {
		Exam.totalNumExams = totalNumExams;
	}

	/* (non-Javadoc)
	 * returns the hash code of this object
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((examID == null) ? 0 : examID.hashCode());
		return result;
	}

	/* (non-Javadoc)
	 * compares this object to the parameter
	 * @see java.lang.Object#equals(java.lang.Object)
	 * @return true if the examID is equal, false otherwise
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Exam other = (Exam) obj;
		if (examID == null) {
			if (other.examID != null)
				return false;
		} else if (!examID.equals(other.examID))
			return false;
		return true;
	}

	/* (non-Javadoc)
	 * Returns a string representation of this object
	 * @see java.lang.Object#toString()
	 * @return the string representation
	 */
	@Override
	public String toString() {
		return "Exam [examID=" + examID + ", examName=" + examName
				+ ", questions=" + questions + "]";
	}
	
	/**
	 * Adds a TrueOrFalse question to the exam
	 * 
	 * @param questionText the question string
	 * @param answer the correct answer, either True or False
	 * @see TrueOrFalse
	 */
	public void addQuestion(String questionText,String answer){
		TrueOrFalse question = new TrueOrFalse(questionText, answer);
		questions.add(question);
	}

	/**
	 * Adds a MultipleChoice question to the exam
	 * 
	 * @param questionText the question string
	 * @param answer the correct answer, must be included in the choices parameter
	 * @param choices an ArrayList of the available choices for the question
	 */
	public void addQuestion(String questionText,String answer,ArrayList<String> choices){
		MultipleChoice question = new MultipleChoice(questionText, answer, choices);
		questions.add(question);
	}

	/**
	 * sets the length of the exam
	 * 
	 * @param duration length of the exam in seconds
	 */
	public void setDuration(long duration) {
		this.duration = duration;
	}

	/**
	 * the length of this exam in seconds
	 * 
	 * @return returns the length in seconds
	 */
	public long getDuration() {
		return duration;
	}

	/**
	 * Changes the passing percent value
	 * 
	 * @param passingPercent new passing percentage
	 */
	public void setPassingPercent(double passingPercent) {
		this.passingPercent = passingPercent;
	}

	/**
	 * Returns the passing percent value
	 * 
	 * @return double representing the passing value
	 */
	public double getPassingPercent() {
		return passingPercent;
	}

	/**
	 * Returns a true/false value if the exam is still available for editing.
	 * True if the exam is still editable, false if otherwise.
	 * 
	 * @return
	 */
	public boolean isDraft() {
		return draft;
	}

	/**
	 * Sets a true/false value to signify if the exam is still available for editing.
	 * 
	 * @param draft
	 */
	public void setDraft(boolean draft) {
		this.draft = draft;
	}

	/**
	 * Searches the exam for a question in its list, Returns null if there's no such question
	 * 
	 * @param questionID - ID of the question
	 * @return
	 */
	public Question searchQuestion(String questionID){
		Question question = null;
		
		for(Question q: questions){
			if(q.getQuestionID().equals(questionID)){
				question = questions.get(questions.indexOf(q)); 
				break;
			}
		}
		return question;
	}
}